package controller

import (
	"fmt"
	"gopkg.in/yaml.v3"
	"log"
	"os"
	"time"

	mqtt "github.com/eclipse/paho.mqtt.golang"
)

type MQTTConfig struct {
	Broker               string `yaml:"broker"`
	ClientID             string `yaml:"clientID"`
	TopicFmt             string `yaml:"topicFmt"`
	Username             string `yaml:"username"`
	Password             string `yaml:"password"`
	KeepAlive            int    `yaml:"keepAlive"`   // 修改: 将 time.Duration 改为 int
	PingTimeout          int    `yaml:"pingTimeout"` // 修改: 将 time.Duration 改为 int
	AutoReconnect        bool   `yaml:"autoReconnect"`
	ConnectRetry         bool   `yaml:"connectRetry"`
	ConnectRetryInterval int    `yaml:"connectRetryInterval"` // 修改: 将 time.Duration 改为 int
}

var config MQTTConfig

func loadConfig() error {
	// 获取环境变量中的配置文件路径
	configPath := os.Getenv("CONFIG_PATH")
	if configPath == "" {
		configPath = "config.yaml" // 默认配置文件路径
	}

	// 读取配置文件
	data, err := os.ReadFile(configPath)
	if err != nil {
		return fmt.Errorf("读取配置文件失败: %v", err)
	}

	// 解析配置文件
	err = yaml.Unmarshal(data, &config)
	if err != nil {
		return fmt.Errorf("解析配置文件失败: %v", err)
	}

	return nil
}

// 发布消息到MQTT服务器
func publishToMQTT(modelType string, sn string, payload string) error {
	// 加载配置
	err := loadConfig()
	if err != nil {
		return fmt.Errorf("加载配置失败: %v", err)
	}

	// 创建MQTT客户端选项
	opts := mqtt.NewClientOptions()
	opts.SetUsername(config.Username)
	opts.SetPassword(config.Password)
	opts.AddBroker(config.Broker)
	opts.SetClientID(config.ClientID + "-" + sn)
	opts.SetKeepAlive(time.Duration(config.KeepAlive) * time.Second)     // 修改: 将 int 转换为 time.Duration
	opts.SetPingTimeout(time.Duration(config.PingTimeout) * time.Second) // 修改: 将 int 转换为 time.Duration
	opts.SetAutoReconnect(config.AutoReconnect)
	opts.SetConnectRetry(config.ConnectRetry)
	opts.SetConnectRetryInterval(time.Duration(config.ConnectRetryInterval) * time.Second) // 修改: 将 int 转换为 time.Duration

	// 添加重连次数限制
	var retryCount int
	opts.SetConnectionLostHandler(func(client mqtt.Client, err error) {
		retryCount++
		if retryCount > 3 {
			log.Printf("MQTT连接失败，已尝试重连3次，放弃重连: %v", err)
			return
		}
		log.Printf("MQTT连接丢失，正在尝试第%d次重连: %v", retryCount, err)
	})

	log.Printf("准备连接到MQTT服务器: %s", config.Broker)
	// 连接回调
	opts.SetOnConnectHandler(func(client mqtt.Client) {
		log.Printf("已连接到MQTT服务器: %s", config.Broker)
	})

	// 创建客户端
	client := mqtt.NewClient(opts)
	log.Printf("客户端状态 %v", client.IsConnected())

	// 连接到服务器
	if token := client.Connect(); token.Wait() && token.Error() != nil {
		return fmt.Errorf("MQTT连接失败: %v", token.Error())
	}

	// 确保函数结束时断开连接
	defer client.Disconnect(250)

	// 构建主题
	topic := fmt.Sprintf(config.TopicFmt, modelType, sn)

	// 发布消息
	log.Printf("发布MQTT消息到主题: %s", topic)
	token := client.Publish(topic, 0, false, payload)

	// 等待发布完成
	if token.Wait() && token.Error() != nil {
		return fmt.Errorf("MQTT消息发布失败: %v", token.Error())
	}

	log.Printf("MQTT消息发布成功")
	return nil
}
